package com.northpool.operator.utils;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.northpool.operator.IOperatorHandler;
import com.northpool.operator.serve.HttpSessionRestImpl;
import com.northpool.operator.serve.IServeEndpoint;
import fi.iki.elonen.NanoHTTPD;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public abstract class ServeOperatorHelper extends NanoHTTPD implements IOperatorHandler {
    protected Map<String, IServeEndpoint> endpoints = new LinkedHashMap<>();

    public ServeOperatorHelper(int port) {
        super(port);
        try {
            start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
            Console.log("服务启动成功, 端口: {}", port);
        } catch (IOException e) {
            Console.error("服务启动失败: {}", e.getMessage(), e);
            this.failedExit();
        }
        this.addOpenAPI();
    }

    public void addEndpoint(String uri, Method method, IServeEndpoint iServeEndpoint) {
        String key = buildEndpointKey(method, uri);
        endpoints.put(key, iServeEndpoint);
    }

    private String buildEndpointKey(Method method, String uri) {
        return StrUtil.format("{}_{}", method.name(), uri);
    }

    private void addOpenAPI() {
        endpoints.put(this.buildEndpointKey(Method.GET, "/openapi.json"), session -> "openapi");
    }

    @Override
    public Response serve(IHTTPSession session) {
        Method method = session.getMethod();
        String uri = session.getUri();

        String mimetype = "application/json";
        // 解决中文乱码问题
        ContentType ct = new ContentType(session.getHeaders().get("content-type")).tryUTF8();
        session.getHeaders().put("content-type", ct.getContentTypeHeader());

        String responseTxt = "";
        String key = this.buildEndpointKey(method, uri);
        if (endpoints.containsKey(key)) {
            IServeEndpoint iServeEndpoint = endpoints.get(key);
            try {
                Object response = iServeEndpoint.handler(new HttpSessionRestImpl(session));
                responseTxt = JSONObject.toJSONString(response);
                return newFixedLengthResponse(Response.Status.OK, mimetype, responseTxt);
            } catch (Exception ex) {
                return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, mimetype, ex.getMessage());
            }
        } else {
            return newFixedLengthResponse(Response.Status.NOT_FOUND, mimetype, responseTxt);
        }
    }

    /**
     * 异常退出
     */
    public void failedExit() {
        System.exit(10);
    }

    /**
     * 异常日志
     *
     * @param msg 错误信息
     */
    public void error(Object msg) {
        Console.error(msg);
    }

    /**
     * 异常日志
     *
     * @param template 日志模板
     * @param args     日志参数
     */
    public void error(String template, Object... args) {
        Console.error(template, args);
    }


    /**
     * 普通日志输出
     *
     * @param template 日志模板
     * @param args     日志参数
     */
    public void log(String template, Object... args) {
        Console.log(template, args);
    }

    /**
     * 普通日志输出
     *
     * @param msg 日志信息
     */
    public void log(Object msg) {
        Console.log(msg);
    }
}
